package com.lfy.modules.blog.controller;

import cn.hutool.extra.spring.SpringUtil;
import com.lfy.aop.anno.CheckFile;
import com.lfy.aop.enums.LegalFileTypeEnum;
import com.lfy.modules.blog.domain.dto.article.ArticleDTO;
import com.lfy.modules.blog.domain.dto.article.CommentDTO;
import com.lfy.modules.blog.domain.dto.article.ModifyArticleDTO;
import com.lfy.modules.blog.domain.event.ClearHomeArticleCacheEvent;
import com.lfy.modules.blog.domain.event.ClearWebArticleDetailEvent;
import com.lfy.modules.blog.domain.group.SaveGroup;
import com.lfy.modules.blog.domain.group.WebGroup;
import com.lfy.modules.blog.domain.vo.article.ArticleVO;
import com.lfy.modules.blog.domain.vo.article.ClassificationListVO;
import com.lfy.modules.blog.domain.vo.article.TagListVO;
import com.lfy.modules.blog.service.ArticleClassificationService;
import com.lfy.modules.blog.service.ArticleService;
import com.lfy.modules.blog.service.ArticleTagService;
import com.lfy.modules.common.anno.Authentication;
import com.lfy.modules.common.anno.AutoUser;
import com.lfy.modules.common.custom.constants.FileConstant;
import com.lfy.modules.common.custom.constants.PageConstant;
import com.lfy.modules.common.domain.PageResultVO;
import com.lfy.modules.common.domain.R;
import com.lfy.modules.common.domain.entity.UserEntity;
import org.hibernate.validator.constraints.Length;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 文章管理
 *
 * @author <a href="https://www.lvfeiy.top">lvfeiyang</a>
 * @date 2024/5/2 16:34
 */
@RequestMapping("/admin/article")
@RestController
@Validated
public class ArticleController {
    @Resource
    private ArticleService articleService;
    @Resource
    private ArticleTagService tagService;
    @Resource
    private ArticleClassificationService articleClassificationService;

    /**
     * 获取文章标签列表
     */
    @GetMapping("/get/tags")
    public R<List<TagListVO>> getTags() {
        return tagService.getTags();
    }
    /**
     * 添加文章标签
     */
    @PostMapping("/add/tag")
    @Authentication("blog:tag:save")
    public R<Void> addTag(@NotBlank(message = "标签名称不能为空") @Length(max = 14, message = "标签名称长度不能超过14") String tagName) {
        return tagService.addTag(tagName);
    }
    /**
     * 删除文章标签
     */
    @PostMapping("/delete/tag")
    @Authentication("blog:tag:remove")
    public R<Void> deleteTag( @NotNull(message = "标签id不能为空")  Long tagId) {
        return tagService.deleteTag(tagId);
    }
    /**
     * 获取分类列表
     */

    @GetMapping("/get/categories")
    public R<List<ClassificationListVO>> getCategories() {
        return articleClassificationService.getCategories();
    }
    /**
     * 添加分类
     */
    @PostMapping("/add/category")
    @Authentication("blog:fl:save")
    public R<Void> addCategory(@NotBlank(message = "分类名称不能为空") @Length(max = 14, message = "分类名称长度不能超过14") String categoryName) {
        return articleClassificationService.addCategory(categoryName);
    }
    /**
     * 删除分类
     */
    @PostMapping("/delete/category")
    @Authentication("blog:fl:remove")
    public R<Void> deleteCategory(@NotNull(message = "分类id不能为空") Long categoryId) {
        return articleClassificationService.deleteCategory(categoryId);
    }
    /**
     * 发布文章
     */
    @PostMapping("/add/article")
    @Authentication("blog:article:publish")
    public R<Void> addArticle(@Validated(SaveGroup.class)  ArticleDTO dto, @AutoUser UserEntity user) {
        MultipartFile imgFile = dto.getImgFile();
        if (imgFile.getSize() > FileConstant.MAX_IMG_FILE_SIZE) {
            return R.error("图片大小不能超过10M");
        }
        String contentType = imgFile.getContentType();

        if (contentType == null || !contentType.startsWith(FileConstant.IMG_FILE_PREFIX)) {
            return R.error("图片格式不正确");
        }

        SpringUtil.publishEvent( new ClearHomeArticleCacheEvent(this,user.getId()));
        return this.articleService.saveArticle(dto,user);
    }
    /**
     * 文章内图片上传
     */

    @PostMapping("/upload/img")
    @Authentication("blog:article:publish")
    @CheckFile({LegalFileTypeEnum.JPG,LegalFileTypeEnum.PNG})
    public R<List<String>> uploadImg(@AutoUser UserEntity user, @RequestParam("files") MultipartFile[] files) {
        for (MultipartFile file : files) {
            if (file.getSize() > FileConstant.MAX_IMG_FILE_SIZE) {
                return R.error("图片大小不能超过10M");
            }
            String contentType = file.getContentType();

            if (contentType == null || !contentType.startsWith(FileConstant.IMG_FILE_PREFIX)) {
                return R.error("图片格式不正确");
            }
        }
        return this.articleService.uploadImg(user, files);
    }

    /**
     * 获取当前登录用户的文章列表
     * @param pageNum 页码
     * @param pageSize 每页数量
     * @return R
     */
    @GetMapping("/get/articleList")
    public R<PageResultVO<ArticleVO>> getArticleList(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
                                                     @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        if(pageSize > PageConstant.MAX_PAGE_SIZE){
            return R.error("每页数量不能超过"+PageConstant.MAX_PAGE_SIZE);
        }
        return this.articleService.getArticleList(pageNum, pageSize);
    }

    /**
     * 更改是否推荐
     * @param articleId 文章id
     * @param recommend 推荐状态
     * @return R
     */
    @PostMapping("/modify/recommend")
    @Authentication("blog:article:modify")
    public R<Void> modifyRecommend(@NotNull(message = "文章id不能为空") Long articleId,@NotNull(message = "推荐状态不能为空") Integer recommend,@AutoUser UserEntity user){
        R<Void> r = this.articleService.modifyRecommend(articleId, recommend);
        SpringUtil.publishEvent( new ClearHomeArticleCacheEvent(this,user.getId()));
        return r;
    }

    /**
     * 上架文章
     * @param articleId 文章id
     * @return R
     */
    @PostMapping("/up")
    @Authentication("blog:article:modify")
    public R<Void> upArticle(@NotNull(message = "文章id不能为空") Long articleId,@AutoUser UserEntity user){
        R<Void> r = this.articleService.upArticle(articleId);
        SpringUtil.publishEvent( new ClearHomeArticleCacheEvent(this,user.getId()));
        return r;
    }

    /**
     * 下架文章
     * @param articleId 文章id
     * @return R
     */
    @PostMapping("/down")
    @Authentication("blog:article:modify")
    public R<Void> downArticle(@NotNull(message = "文章id不能为空") Long articleId,@AutoUser UserEntity user){
        R<Void> r = this.articleService.downArticle(articleId);
        SpringUtil.publishEvent( new ClearHomeArticleCacheEvent(this,user.getId()));
        SpringUtil.publishEvent( new ClearWebArticleDetailEvent(this,articleId));
        return r;
    }
    /**
     * 删除文章
     * @param articleId 文章id
     * @return R
     */
    @PostMapping("/delete/article")
    @Authentication("blog:article:remove")
    public R<Void> deleteArticle(@NotNull(message = "文章id不能为空") Long articleId,@AutoUser UserEntity user){
        R<Void> r = this.articleService.deleteArticle(articleId);
        SpringUtil.publishEvent( new ClearHomeArticleCacheEvent(this,user.getId()));
        SpringUtil.publishEvent( new ClearWebArticleDetailEvent(this,articleId));

        return r;
    }

    /**
     * 修改文章
     * @param dto dto
     * @param user 用户
     * @return R
     */
    @PostMapping("/modify/article")
    @Authentication("blog:article:modify")
    public R<Void> modifyArticle(@Validated @RequestBody ModifyArticleDTO dto, @AutoUser UserEntity user) {
        R<Void> r = this.articleService.modifyArticle(dto, user);
        SpringUtil.publishEvent( new ClearHomeArticleCacheEvent(this,user.getId()));
        SpringUtil.publishEvent( new ClearWebArticleDetailEvent(this,dto.getId()));
        return r;
    }
    /**
     * 修改封面
     */
    @PostMapping("/modify/cover")
    @Authentication("blog:article:modify")
    @CheckFile({LegalFileTypeEnum.JPG,LegalFileTypeEnum.PNG})
    public R<Void> modifyCover(@NotNull(message = "文章id不能为空") Long articleId, @NotNull(message = "封面不能为空") MultipartFile file, @AutoUser UserEntity user) {
        if (file.getSize() > FileConstant.MAX_IMG_FILE_SIZE) {
            return R.error("图片大小不能超过10M");
        }
        String contentType = file.getContentType();

        if (contentType == null || !contentType.startsWith(FileConstant.IMG_FILE_PREFIX)) {
            return R.error("图片格式不正确");
        }
        R<Void> r = this.articleService.modifyCover(articleId, file);
        SpringUtil.publishEvent( new ClearHomeArticleCacheEvent(this,user.getId()));
        SpringUtil.publishEvent( new ClearWebArticleDetailEvent(this,articleId));
        return r;
    }

}
